﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace TA.DotNetUtils
{
	public class IdValue<I, T, P> : SimpleIdValue<I, T, P>
		where I : struct
		where T : IHasId<I>, IFromDataRow, IFromDataSet, new()
		where P : BaseProvider<I, T>, new()
	{

		T _leanValue;

		public IdValue(I id)
			: base(id)
		{
		}
		public IdValue(T value)
			: base(value)
		{
		}
		public T LeanValue
		{
			get
			{
				if (_leanValue == null)
				{
					_leanValue = new T { GenericId = Id };
				}
				return _leanValue;
			}
			set
			{
				Id = (I)value.GenericId;
			}
		}
		public static implicit operator IdValue<I, T, P>(I id)
		{
			return new IdValue<I, T, P>(id);
		}
		public static implicit operator IdValue<I, T, P>(T value)
		{
			if (value == null)
				return null;
			return new IdValue<I, T, P>(value);
		}
		public static implicit operator I(IdValue<I, T, P> idValue)
		{
			if (idValue == null) return default(I);
			return idValue.Id;
		}
		public static implicit operator I?(IdValue<I, T, P> idValue)
		{
			if (idValue == null) return null;
			return idValue.Id;
		}
		public static implicit operator IdValue<I, T>(IdValue<I, T, P> idValue)
		{
			if (idValue == null) return null;
			if (idValue.HasValue)
				return idValue.Value;
			return idValue.Id;
		}
		public static implicit operator IdValue<I, T, P>(IdValue<I, T> idValue)
		{
			if (idValue == null) return null;
			if (idValue.HasValue)
				return idValue.Value;
			return idValue.Id;
		}
	}
	//public class IdValue<I, T, P, U> : SimpleIdValue<I, T, P, U>
	//  where I : struct
	//  where T : IHasId<I>, IFromDataRow, IFromDataSet, new()
	//  where P : BaseProvider<I, T, U>, new()
	//  where U : IHasGenericId
	//{

	//  T _leanValue;

	//  public IdValue(I id)
	//    : base(id)
	//  {
	//  }
	//  public IdValue(T value)
	//    : base(value)
	//  {
	//  }
	//  public T LeanValue
	//  {
	//    get
	//    {
	//      if (_leanValue == null)
	//      {
	//        _leanValue = new T { GenericId = Id };
	//      }
	//      return _leanValue;
	//    }
	//    set
	//    {
	//      Id = (I)value.GenericId;
	//    }
	//  }
	//  public static implicit operator IdValue<I, T, P, U>(I id)
	//  {
	//    return new IdValue<I, T, P, U>(id);
	//  }
	//  public static implicit operator IdValue<I, T, P, U>(T value)
	//  {
	//    if (value == null)
	//      return null;
	//    return new IdValue<I, T, P, U>(value);
	//  }
	//  public static implicit operator I(IdValue<I, T, P, U> idValue)
	//  {
	//    if (idValue == null) return default(I);
	//    return idValue.Id;
	//  }
	//  public static implicit operator I?(IdValue<I, T, P, U> idValue)
	//  {
	//    if (idValue == null) return null;
	//    return idValue.Id;
	//  }
	//  public static implicit operator T(IdValue<I, T, P, U> idValue)
	//  {
	//    if (idValue == null) return default(T);
	//    return idValue.Value;
	//  }
	//}
}
